home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 June: Reference Library / Dev.CD Jun 99 RL Disk 1.toast / Technical Documentation / Develop / develop Issue 28 / develop Issue 28 code / Sketch / Source / AppleEvent / OSLClassWindow.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-08-25  |  39.8 KB  |  1,651 lines  |  [TEXT/CWIE]

  1. /****************************************************************************
  2.  * 
  3.  * OSLClassWindow.c
  4.  *
  5.  ****************************************************************************/
  6.  
  7. #include "OSLClassWindow.h"
  8. #include "WindowUtils.h"
  9.  
  10. #include "AppleEvent.h"
  11.  
  12. #include "Documents.h"
  13. #include "DocumentHelpers.h"
  14. #include "DocumentADT.h"
  15.  
  16. #include "OSLHelpers.h"
  17. #include "AERCoreSuite.h"
  18.  
  19. #include "Assertion.h"
  20.  
  21. // ----------------------------------------------------------------------------
  22. //                      Core Suite Object Event handlers
  23. // ----------------------------------------------------------------------------
  24.  
  25. static OSErr HandleClose        (AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply);
  26. static OSErr HandleCount        (AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply);
  27. static OSErr HandleDataSize    (AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply);
  28. static OSErr HandleDelete        (AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply);
  29. static OSErr HandleDuplicate    (AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply);
  30. static OSErr HandleExists        (AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply);
  31. static OSErr HandleGetData        (AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply);
  32. static OSErr HandleMake            (AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply);
  33. static OSErr HandleMove            (AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply);
  34. static OSErr HandleOpen            (AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply);
  35. static OSErr HandlePrint        (AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply);
  36. static OSErr HandleQuit            (AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply);
  37. static OSErr HandleSave            (AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply);
  38. static OSErr HandleSetData        (AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply);
  39.  
  40. // ----------------------------------------------------------------------------
  41. //                      Core Suite Object Accessor functions
  42. // ----------------------------------------------------------------------------
  43.  
  44. static pascal OSErr 
  45. WindowFromApplicationAccessor(         
  46.                 DescType        desiredClass,
  47.         const AEDesc*        containerToken,
  48.                 DescType        containerClass, 
  49.                 DescType        keyForm,
  50.         const AEDesc*        keyData,
  51.                 AEDesc*        resultToken,
  52.                 long             refCon);
  53.                                          
  54. static OSErr 
  55. PropertyFromListAccessor(
  56.                  DescType        desiredClass,
  57.         const AEDesc*        containerToken,
  58.                 DescType        containerClass,
  59.                 DescType        keyForm,
  60.         const AEDesc*        keyData,
  61.                 AEDesc*        resultToken,
  62.                 long             refCon);
  63.                                          
  64. static OSErr 
  65. PropertyFromObjectAccessor(
  66.                  DescType        desiredClass,
  67.         const AEDesc*        containerToken,
  68.                 DescType        containerClass,
  69.                 DescType        keyForm,
  70.         const AEDesc*        keyData,
  71.                 AEDesc*        resultToken,
  72.                 long             refCon);
  73.  
  74. static OSErr        GetDataFromObject        (AEDesc *token,   AEDesc *desiredTypes, AEDesc *data);
  75. static OSErr        GetDataFromList        (AEDesc *srcList, AEDesc *desiredTypes, AEDesc *dstList);
  76.  
  77. static OSErr        SetDataForList            (AEDesc *token, AEDesc *data);
  78. static OSErr        SetDataForObject        (AEDesc *token, AEDesc *data);
  79.  
  80.  
  81. static Boolean        CanGetProperty            (DescType property);
  82. static Boolean        CanSetProperty            (DescType property);
  83. static OSErr         SetProperties            (WindowPtr window, AEDesc *propertyRecord);
  84.  
  85. // ----------------------------------------------------------------------------
  86. //                      Core Suite Object Accessor helper functions
  87. // ----------------------------------------------------------------------------
  88.  
  89. static OSErr             DoClose                            (AEDesc *token, const AEDesc *saving, AEDesc *savingIn);
  90. static OSErr             DoOpen                            (AEDesc *token);
  91.  
  92. static OSErr             ProcessFormRelativePostition(const AEDesc* anchorToken, const AEDesc *keyData, WindowPtr *window);
  93.  
  94. /*****************************************************************************
  95.  * 
  96.  * WindowEventDispatcher
  97.  *
  98.  *    Handles all OSL messages that cDocument should handle
  99.  * 
  100.  *****************************************************************************/
  101.  
  102. OSErr
  103. WindowEventDispatcher(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply, long refcon)
  104. {
  105.     #pragma unused (refcon)
  106.  
  107.     OSErr error = noErr;
  108.     
  109.     AEEventID    eventID;
  110.     OSType        typeCode;
  111.     Size            actualSize = 0L;
  112.     
  113.     // Get the event ID
  114.     
  115.     error = AEGetAttributePtr(appleEvent, 
  116.                                       keyEventIDAttr, 
  117.                                       typeType, 
  118.                                       &typeCode, 
  119.                                       (Ptr)&eventID, 
  120.                                       sizeof(eventID), 
  121.                                       &actualSize);
  122.                                       
  123.     if (error != noErr) {
  124.         return error;
  125.     }
  126.     
  127.     switch (eventID) {
  128.     
  129.         case kAEClone:
  130.             error = HandleDuplicate(token, appleEvent, reply);
  131.             break;
  132.             
  133.         case kAEClose:
  134.             error = HandleClose(token, appleEvent, reply);
  135.             break;
  136.             
  137.         case kAECountElements:
  138.             error = HandleCount(token, appleEvent, reply);
  139.             break;
  140.             
  141.         case kAECreateElement:
  142.             error = HandleMake(token, appleEvent, reply);
  143.             break;
  144.             
  145.         case kAEDelete:
  146.             error = HandleDelete(token, appleEvent, reply);
  147.             break;
  148.             
  149.         case kAEDoObjectsExist:
  150.             error = HandleExists(token, appleEvent, reply);
  151.             break;
  152.             
  153.         case kAEGetData:
  154.             error = HandleGetData(token, appleEvent, reply);
  155.             break;
  156.             
  157.         case kAEGetDataSize:
  158.             error = HandleDataSize(token, appleEvent, reply);
  159.             break;
  160.             
  161.         case kAEMove:
  162.             error = HandleMove(token, appleEvent, reply);
  163.             break;
  164.             
  165.         case kAEOpen:
  166.             error = HandleOpen(token, appleEvent, reply);
  167.             break;
  168.             
  169.         case kAEPrint:
  170.             error = HandlePrint(token, appleEvent, reply);
  171.             break;
  172.             
  173.         case kAEQuitApplication:
  174.             error = HandleQuit(token, appleEvent, reply);
  175.             break;
  176.             
  177.         case kAESave:
  178.             error = HandleSave(token, appleEvent, reply);
  179.             break;
  180.             
  181.         case kAESetData:
  182.             error = HandleSetData(token, appleEvent, reply);
  183.             break;
  184.  
  185.         default:
  186.             error = errAEEventNotHandled;
  187.             break;
  188.     }
  189.     
  190.     return error;
  191. }
  192.  
  193. #pragma mark -
  194. // ----------------------------------------------------------------------------
  195. //                      Core Suite Object Event handlers
  196. // ----------------------------------------------------------------------------
  197.  
  198. static OSErr 
  199. HandleClose(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
  200. {
  201.     #pragma unused (reply)
  202.  
  203.     OSErr         error     = noErr;
  204.     
  205.     DescType        typeCode = 0L;
  206.     
  207.     AEDesc        saving    = {typeNull, nil};
  208.     AEDesc        savingIn = {typeNull, nil};
  209.     
  210.     AEDesc      *ptrToSaving    = NULL;
  211.     AEDesc      *ptrToSavingIn = NULL;
  212.     
  213.     // Extract the [saving yes/no/ask] optional parameter, if present
  214.     
  215.     error = AEGetParamDesc(appleEvent, keyAESaveOptions, typeWildCard, &saving);
  216.     
  217.     if (error == noErr)
  218.         ptrToSaving = &saving;
  219.     else if (error == errAEDescNotFound)
  220.        error = noErr;
  221.     else
  222.         goto Cleanup;
  223.     
  224.     // Extract the [saving in <alias>] optional parameter, if present
  225.     
  226.     error = AEGetParamDesc(appleEvent, keyAEFile, typeFSS, &savingIn);
  227.     
  228.     if (error == noErr)
  229.         ptrToSavingIn = &savingIn;
  230.     else if (error == errAEDescNotFound)
  231.        error = noErr;
  232.     else
  233.         goto Cleanup;
  234.  
  235.     // Check for any required parameters we may have missed
  236.     
  237.     error = CheckForUnusedParameters(appleEvent);
  238.     if (error != noErr)
  239.         goto Cleanup;
  240.         
  241.     // Now, do the application-related work
  242.  
  243.     if (TokenContainsTokenList(token))
  244.     {
  245.         AEDesc        windowToken = {typeNull, nil};
  246.         long            numItems;
  247.         long            itemNum;
  248.         AEKeyword    keyword;
  249.                 
  250.         if (error == noErr)
  251.         {
  252.             error = AECountItems(token, &numItems);
  253.             if (error == noErr || numItems > 0)
  254.             {
  255.                 for (itemNum = 1; itemNum <= numItems; itemNum++)
  256.                 {
  257.                    error = AEGetNthDesc(token, itemNum, typeWildCard, &keyword, &windowToken);
  258.                    
  259.                     if (error == noErr)
  260.                         error = DoClose(&windowToken, ptrToSaving, ptrToSavingIn);
  261.                     else
  262.                         break;
  263.                         
  264.                     AEDisposeDesc(&windowToken);
  265.                 }
  266.             }
  267.         }
  268.         AEDisposeDesc(&windowToken);
  269.     }
  270.     else
  271.     {
  272.         error = DoClose(token, ptrToSaving, ptrToSavingIn);
  273.     }
  274.  
  275. Cleanup:
  276.  
  277.     AEDisposeDesc(&saving);
  278.     AEDisposeDesc(&savingIn);
  279.         
  280.     return error;
  281.  
  282. }
  283.  
  284. // ----------------------------------------------------------------------------
  285. // Count things IN a window, not count windows
  286. // Not implement. Count things in documents, not windows, in this implementation.
  287.  
  288. static OSErr 
  289. HandleCount(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
  290. {
  291.     #pragma unused (token, appleEvent, reply)
  292.  
  293.     OSErr        error = errAEEventNotHandled;    
  294.  
  295.     return error;
  296.     
  297. }
  298.  
  299. // ----------------------------------------------------------------------------
  300.  
  301. static OSErr 
  302. HandleDataSize(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
  303. {
  304.     #pragma unused (token, appleEvent, reply)
  305.  
  306.     OSErr error = errAEEventNotHandled;
  307.     
  308.     return error;
  309. }
  310.  
  311. // ----------------------------------------------------------------------------
  312.  
  313. static OSErr 
  314. HandleDelete(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
  315. {
  316.     #pragma unused (token, appleEvent, reply)
  317.  
  318.     OSErr error = errAEEventNotHandled;
  319.     
  320.     return error;
  321. }
  322.  
  323. // ----------------------------------------------------------------------------
  324.  
  325. static OSErr 
  326. HandleDuplicate(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
  327. {
  328.     #pragma unused (token, appleEvent, reply)
  329.  
  330.     OSErr error = errAEEventNotHandled;
  331.     
  332.     return error;
  333. }
  334.  
  335. // ----------------------------------------------------------------------------
  336. // If <anObject> exists...
  337. // The AEResolve() function in AERCoreSuite.c will already have filtered
  338. // out all cases where the object did not exist, so this function should
  339. // always return TRUE.
  340.  
  341. static OSErr 
  342. HandleExists(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
  343. {
  344.     #pragma unused (token, appleEvent)
  345.  
  346.     OSErr error         = noErr;
  347.     Boolean foundIt    = true;
  348.  
  349.     error = AEPutParamPtr(reply, 
  350.                      keyAEResult, 
  351.                      typeBoolean, 
  352.                      (Ptr)&foundIt, 
  353.                      sizeof(Boolean));
  354.         
  355.     return error;
  356. }
  357.  
  358. // ----------------------------------------------------------------------------
  359.  
  360. static OSErr 
  361. HandleGetData(AEDesc *tokenOrTokenList, const AppleEvent *appleEvent, AppleEvent *reply)
  362. {
  363.     OSErr             error             = noErr;    
  364.     AEDesc            data                 = {typeNull, nil};
  365.     AEDesc            desiredTypes   = {typeNull, nil};
  366.     
  367.     AEGetParamDesc(appleEvent, keyAERequestedType, typeAEList, &desiredTypes);
  368.     
  369.     error = GetDataFromWindow(tokenOrTokenList, &desiredTypes, &data);
  370.  
  371.     if (error == noErr && reply->descriptorType != typeNull)
  372.         error = AEPutKeyDesc(reply, keyDirectObject, &data);
  373.         
  374.     AEDisposeDesc(&data);
  375.     AEDisposeDesc(&desiredTypes);
  376.     
  377.     return error;
  378. }
  379.  
  380. // ----------------------------------------------------------------------------
  381.  
  382. static OSErr 
  383. HandleMake(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
  384. {
  385.     #pragma unused (token, appleEvent, reply)
  386.  
  387.     OSErr error = errAEEventNotHandled;
  388.     
  389.     return error;
  390. }
  391.  
  392. // ----------------------------------------------------------------------------
  393.  
  394. static OSErr 
  395. HandleMove(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
  396. {
  397.     #pragma unused (token, appleEvent, reply)
  398.  
  399.     OSErr error = errAEEventNotHandled;
  400.     
  401.     return error;
  402. }
  403.  
  404. // ----------------------------------------------------------------------------
  405.  
  406. static OSErr 
  407. HandleOpen(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
  408. {
  409.     #pragma unused (reply)
  410.  
  411.     OSErr         error     = noErr;
  412.     
  413.     DescType        typeCode = 0L;
  414.  
  415.     // Check for any required parameters we may have missed
  416.     
  417.     error = CheckForUnusedParameters(appleEvent);
  418.     if (error != noErr)
  419.         goto Cleanup;
  420.         
  421.     // Now, do the application-related work
  422.  
  423.     if (TokenContainsTokenList(token))
  424.     {
  425.         AEDescList  flatList     = {typeNull, nil};
  426.         AEDesc        singleToken = {typeNull, nil};
  427.         long            numItems;
  428.         long            itemNum;
  429.         AEKeyword    keyword;
  430.         
  431.         error = AECreateList(NULL, 0L, false, &flatList);
  432.         if (error == noErr)
  433.         {
  434.             error = AECountItems(&flatList, &numItems);
  435.             if (error == noErr || numItems > 0)
  436.             {
  437.                 for (itemNum = 1; itemNum <= numItems; itemNum++)
  438.                 {
  439.                    error = AEGetNthDesc(&flatList, itemNum, typeWildCard, &keyword, &singleToken);
  440.                    
  441.                     if (error == noErr)
  442.                         error = DoOpen(&singleToken);
  443.                     else
  444.                         break;
  445.                         
  446.                     AEDisposeDesc(&singleToken);
  447.                 }
  448.             }
  449.         }
  450.         
  451.         AEDisposeDesc(&flatList);
  452.         AEDisposeDesc(&singleToken);
  453.     }
  454.     else
  455.     {
  456.         error = DoOpen(token);
  457.     }
  458.  
  459. Cleanup:
  460.         
  461.     return error;
  462.  
  463. }
  464.  
  465. // ----------------------------------------------------------------------------
  466.  
  467. static OSErr 
  468. HandlePrint(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
  469. {
  470.     #pragma unused (token, appleEvent, reply)
  471.  
  472.     OSErr error = errAEEventNotHandled;
  473.     
  474.     return error;
  475. }
  476.  
  477. // ----------------------------------------------------------------------------
  478.  
  479. static OSErr 
  480. HandleQuit(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
  481. {
  482.     #pragma unused (token, appleEvent, reply)
  483.  
  484.     OSErr error = errAEEventNotHandled;
  485.     
  486.     return error;
  487. }
  488.  
  489. // ----------------------------------------------------------------------------
  490.  
  491. static OSErr 
  492. HandleSave(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
  493. {
  494.     #pragma unused (token, appleEvent, reply)
  495.  
  496.     OSErr error = errAEEventNotHandled;
  497.     
  498.     return error;
  499. }
  500.  
  501. // ----------------------------------------------------------------------------
  502.  
  503. static OSErr 
  504. HandleSetData(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
  505. {
  506.     #pragma unused (reply)
  507.  
  508.     OSErr             error          = noErr;    
  509.     AEDesc            data           = {typeNull, nil};
  510.     
  511.     DescType             propertyCode;
  512.     DescType            objectClass;
  513.     
  514.     switch (token->descriptorType)
  515.     {
  516.         case typeAEList:
  517.             error = ExtractKeyDataParameter(appleEvent, &data);
  518.             if (error == noErr)
  519.                 error = SetDataForList(token, &data);
  520.             break;
  521.                 
  522.         case cProperty:
  523.             propertyCode     = ExtractPropertyCodeFromToken(token);
  524.             objectClass    = ExtractObjectClassFromToken(token);
  525.             if (CanSetProperty(propertyCode))
  526.             {
  527.                 error = ExtractKeyDataParameter(appleEvent, &data);
  528.                 if (error == noErr)
  529.                     error = SetDataForObject(token, &data);
  530.             }
  531.             else
  532.             {
  533.                 error = errAENotModifiable;
  534.             }
  535.             break;
  536.             
  537.         default:
  538.             error = errAENotModifiable;
  539.             break;
  540.     }
  541.         
  542.     AEDisposeDesc(&data);
  543.     
  544.     return error;
  545. }
  546.  
  547. #pragma mark -
  548. // -----------------------------------------------------------------------------
  549. //                                                Object Accessors
  550. //------------------------------------------------------------------------------
  551.  
  552. OSErr 
  553. InstallWindowAccessors(void)
  554. {
  555.     OSErr error;
  556.     
  557.     error = AEInstallObjectAccessor(cWindow, typeNull, NewOSLAccessorProc(WindowFromApplicationAccessor), 0L, false);
  558.  
  559.     // although windows can't contain other window, 
  560.     // we need this accessor to support formRelativePostion,
  561.     // which sends us one window as a "container" and asks us to find
  562.     // either the window before or after that window
  563.     
  564.     if (error == noErr)
  565.         error = AEInstallObjectAccessor(cWindow, cWindow, NewOSLAccessorProc(WindowFromApplicationAccessor), 0L, false);
  566.  
  567.     if (error == noErr)
  568.         error = AEInstallObjectAccessor(cProperty, cWindow, NewOSLAccessorProc(PropertyFromWindowAccessor), 0L, false);
  569.  
  570.     return error;
  571. }
  572.  
  573. #pragma mark -
  574. //------------------------------------------------------------------------------
  575. //    Retrieve the window from the application container by the key form and return its
  576. //    pointer in the dataHandle field of resultToken.
  577. //------------------------------------------------------------------------------
  578.  
  579. static pascal OSErr 
  580. WindowFromApplicationAccessor(         
  581.                 DescType        desiredClass,        // cWindow
  582.         const AEDesc*        containerToken,    // null container
  583.                 DescType        containerClass,   // cApplication
  584.                 DescType        keyForm,
  585.         const AEDesc*        keyData,
  586.                 AEDesc*        resultToken,        // specified window is returned in result
  587.                 long             refCon)
  588. {
  589.     #pragma unused (containerToken, containerClass, refCon)
  590.  
  591.     OSErr                    error    = noErr;
  592.     WindowPtr            window;
  593.     
  594.     Str255                title;
  595.  
  596.     DescType                keyDataType     = keyData->descriptorType;
  597.     long                    index;
  598.     long                    numWindows;
  599.     
  600.     Boolean                wantsAllItems    = false;
  601.  
  602.     AEDesc                 startObject     =    {typeNull, nil};    // These are used to resolve formRange
  603.     AEDesc                 stopObject        =     {typeNull, nil};
  604.         
  605.     CoreTokenRecord    token;
  606.     InitCoreTokenRecord(&token);
  607.     
  608.     numWindows = CountWindows();
  609.     
  610.     switch (keyForm) {
  611.         case formName:                                                                        // window by name
  612.             if (DescToPString(keyData, title, 255) != noErr)
  613.             {
  614.                 error = errAECoercionFail;
  615.             }
  616.             else
  617.             {
  618.                 window = GetWindowByTitle(title);
  619.                 if (window == nil)
  620.                     error = errAENoSuchObject;
  621.             }
  622.                 
  623.             break;
  624.         
  625.         case formAbsolutePosition:                                                        // window by number
  626.             error = NormalizeAbsoluteIndex(keyData, &index, numWindows, &wantsAllItems);
  627.             if ((error == noErr) && (wantsAllItems == false))
  628.             {
  629.                 window = GetWindowByIndex(index);
  630.                 if (window == nil)
  631.                     error = errAEIllegalIndex;
  632.             }
  633.             break;    
  634.         
  635.         case formRelativePosition:
  636.             error = ProcessFormRelativePostition(containerToken, keyData, &window);
  637.             break;    
  638.         
  639.         case formRange:
  640.             switch (keyDataType)
  641.             {        
  642.                 case typeRangeDescriptor:
  643.                     error = ProcessFormRange((AEDesc *)keyData, &startObject, &stopObject);
  644.                     if (error == noErr)
  645.                     {
  646.                         DescType startType = ExtractDispatchClassFromToken(&startObject);
  647.                         DescType stopType  = ExtractDispatchClassFromToken(&stopObject);
  648.      
  649.                         if (startType != cWindow || stopType != cWindow)
  650.                             error = errAEWrongDataType;
  651.                     }
  652.                     break;
  653.  
  654.                 default:
  655.                     error = errAEWrongDataType;
  656.                     break;    
  657.             }
  658.             break;    
  659.         
  660.         default:
  661.             return errAEEventNotHandled;
  662.     }
  663.     
  664.     // if user asked for all items, and there aren't any,
  665.     // we'll be kind and return an empty list.
  666.  
  667.     if (wantsAllItems && (error == errAENoSuchObject || error == errAEIllegalIndex))
  668.     {
  669.         error = AECreateList(NULL, 0, false, (AEDescList*)resultToken);
  670.         goto CleanUp;
  671.     }
  672.  
  673.     // fill in the result token
  674.  
  675.     if (error == noErr)
  676.     {
  677.         token.dispatchClass   = cWindow;
  678.         token.objectClass         = cWindow;
  679.         token.propertyCode    = typeNull;
  680.  
  681.         if (wantsAllItems)
  682.         {
  683.             error = AECreateList(NULL, 0, false, (AEDescList*)resultToken);
  684.             
  685.             if (error == noErr)
  686.             {
  687.                 for (index = 1; index <= numWindows; index++)
  688.                 {
  689.                     window = GetWindowByIndex(index);
  690.                     if (window == nil)
  691.                         goto CleanUp;
  692.                         
  693.                     token.window = window;
  694.                     
  695.                     error = AEPutPtr(resultToken, 0, desiredClass, &token, sizeof(token));
  696.                     if (error != noErr)
  697.                         goto CleanUp;
  698.                 }
  699.             }
  700.         }
  701.         else if (keyForm == formRange)
  702.         {            
  703.             WindowPtr            beginWindow;
  704.             WindowPtr              endWindow;
  705.             
  706.             long                    beginIndex;
  707.             long                    endIndex;
  708.             
  709.             beginWindow = ExtractWindowPtrFromToken(&startObject);
  710.             beginIndex  = GetWindowIndex(beginWindow);
  711.  
  712.             endWindow = ExtractWindowPtrFromToken(&stopObject);
  713.             endIndex  = GetWindowIndex(endWindow);
  714.                                     
  715.             error = AECreateList(NULL, 0, false, (AEDescList*)resultToken);
  716.             if (error != noErr)
  717.                 goto CleanUp;
  718.                 
  719.             if (beginIndex > endIndex) // swap elements
  720.             {
  721.                 WindowPtr temp;
  722.                 
  723.                 temp             = beginWindow;
  724.                 beginWindow = endWindow;
  725.                 endWindow   = temp;
  726.             }
  727.             
  728.             window = beginWindow;
  729.             while (window != nil)
  730.             {
  731.                 token.window = window;
  732.                 
  733.                 error = AEPutPtr(resultToken, 0, desiredClass, &token, sizeof(token));
  734.                 if (error != noErr)
  735.                     goto CleanUp;
  736.  
  737.                 if (window == endWindow)
  738.                     break;
  739.                 window = GetNextWindow(window);
  740.             }
  741.         }
  742.         else
  743.         {
  744.             token.window = window;
  745.             error = AECreateDesc(desiredClass, &token, sizeof(token), resultToken);
  746.         }
  747.     }
  748.  
  749. CleanUp:
  750.     
  751.     AEDisposeDesc(&startObject);
  752.     AEDisposeDesc(&stopObject);
  753.         
  754.     return error;
  755. }
  756.  
  757. #pragma mark -
  758. //----------------------------------------------------------------------------------
  759. //                                        Window Property Accessor
  760. //----------------------------------------------------------------------------------
  761. // Handles properties from window token or list of window tokens
  762. //
  763. // NOTE: The container can be either a single token, or a list of tokens
  764. // 
  765. //----------------------------------------------------------------------------------
  766.  
  767. pascal OSErr 
  768. PropertyFromWindowAccessor(
  769.                 DescType        desiredClass,
  770.         const AEDesc*        containerToken,
  771.                 DescType        containerClass,
  772.                 DescType        keyForm,
  773.         const AEDesc*        keyData,
  774.                 AEDesc*        resultToken,
  775.                 long             refCon)
  776. {
  777.     OSErr        error            = noErr;
  778.  
  779.     if (TokenContainsTokenList((AEDescList*)containerToken) == false)
  780.     {
  781.         error = PropertyFromObjectAccessor(desiredClass, containerToken, containerClass, keyForm, keyData, resultToken, refCon);
  782.     }
  783.     else
  784.     {
  785.         error = AECreateList(NULL, 0L, false, resultToken);
  786.         if (error == noErr)
  787.             error = PropertyFromListAccessor(desiredClass, containerToken, containerClass, keyForm, keyData, resultToken, refCon);
  788.     }
  789.     
  790.     return error;
  791. }
  792.  
  793. //----------------------------------------------------------------------------------
  794.  
  795. static OSErr 
  796. PropertyFromListAccessor(
  797.              DescType        desiredClass,
  798.     const AEDesc*        containerToken,
  799.             DescType        containerClass,
  800.             DescType        keyForm,
  801.     const AEDesc*        keyData,
  802.             AEDesc*        resultToken,
  803.             long             refCon)
  804. {
  805.     OSErr            error        = noErr;
  806.     long            itemNum;
  807.     long            numItems;
  808.     DescType        keyword;
  809.     AEDesc        srcItem     = {typeNull, nil};
  810.     AEDesc        dstItem     = {typeNull, nil};
  811.     
  812.     error = AECountItems((AEDescList*)containerToken, &numItems);
  813.     if (error != noErr)
  814.         goto CleanUp;
  815.         
  816.     for (itemNum = 1; itemNum <= numItems; itemNum++)
  817.     {
  818.        error = AEGetNthDesc(containerToken, itemNum, typeWildCard, &keyword, &srcItem);
  819.         if (error != noErr)
  820.             goto CleanUp;
  821.         
  822.         if (TokenContainsTokenList(&srcItem) == false)
  823.         {
  824.             error = PropertyFromObjectAccessor(desiredClass, &srcItem, containerClass, keyForm, keyData, &dstItem, refCon);
  825.         }
  826.         else
  827.         {
  828.             error = AECreateList(NULL, 0L, false, &dstItem);
  829.             if (error == noErr)
  830.                 error = PropertyFromListAccessor(desiredClass, &srcItem, containerClass, keyForm, keyData, &dstItem, refCon);
  831.         }
  832.         
  833.         if (error != noErr)
  834.             goto CleanUp;
  835.  
  836.         error = AEPutDesc(resultToken, itemNum, &dstItem);
  837.         if (error != noErr)
  838.             goto CleanUp;
  839.                 
  840.         AEDisposeDesc(&srcItem);
  841.         AEDisposeDesc(&dstItem);
  842.     }
  843.     
  844. CleanUp:
  845.  
  846.     AEDisposeDesc(&srcItem);
  847.     AEDisposeDesc(&dstItem);
  848.  
  849.     return error;
  850. }
  851.  
  852. //----------------------------------------------------------------------------------
  853. //    Return a token representing the property for the containing window.  
  854. // The token is returned with the property and window reference.
  855. //----------------------------------------------------------------------------------
  856.  
  857. static OSErr 
  858. PropertyFromObjectAccessor( 
  859.                 DescType        desiredType,            // cProperty
  860.         const AEDesc*        containerToken,        // Window object token
  861.                   DescType        containerClass,         // cWindow
  862.                   DescType        keyForm,                    // formPropertyID
  863.           const    AEDesc*        keyData,
  864.                   AEDesc*        resultToken,
  865.                   long             refCon     )
  866. {
  867.     #pragma unused (containerClass, keyForm, refCon)
  868.  
  869.     OSErr                        error;    
  870.     DescType                    requestedProperty;
  871.  
  872.     error = AEDuplicateDesc(containerToken, resultToken);
  873.     if (error != noErr)
  874.         return error;
  875.         
  876.     requestedProperty = **(DescType**)(keyData->dataHandle);
  877.     
  878.     if (requestedProperty == kAEAll)
  879.         requestedProperty = pProperties;
  880.  
  881.     if (CanGetProperty(requestedProperty) || CanSetProperty(requestedProperty))
  882.     {
  883.         resultToken->descriptorType = desiredType;
  884.         (**(CoreTokenHandle)(resultToken->dataHandle)).propertyCode = requestedProperty;
  885.     }
  886.     else
  887.     {
  888.         error = errAEEventNotHandled;
  889.     }
  890.     
  891.     return error;
  892. }
  893.  
  894. #pragma mark -
  895.  
  896. // -------------------------------------------------------------------------------------------
  897. //
  898. //   GetDataFromWindow
  899. //
  900. // Given a token that contains information about a window object, access the object
  901. // to extract the relevant data, and return it to the caller in the "data" parameter.
  902. //
  903. // PUBLIC: also called from the ObjectComparison callback function
  904. //
  905. // The first parameter contains either a single token or a list of tokens
  906. // The second parameter is NULL or a list of preferred types for the return data
  907. //
  908. // -------------------------------------------------------------------------------------------
  909.  
  910. OSErr
  911. GetDataFromWindow(AEDesc *tokenOrTokenList, AEDesc *desiredTypes, AEDesc *data)
  912. {
  913.     OSErr error = noErr;
  914.     
  915.     if (TokenContainsTokenList(tokenOrTokenList) == false)
  916.     {
  917.         error = GetDataFromObject(tokenOrTokenList, desiredTypes, data);
  918.     }
  919.     else
  920.     {
  921.         error = AECreateList(NULL, 0L, false, data);
  922.         if (error == noErr)
  923.             error = GetDataFromList(tokenOrTokenList, desiredTypes, data);
  924.     }
  925.     
  926.     return error;
  927. }
  928.  
  929. // -------------------------------------------------------------------------------------------
  930. //
  931. //   GetDataFromList
  932. //
  933. // -------------------------------------------------------------------------------------------
  934.  
  935. static OSErr
  936. GetDataFromList(AEDesc *srcList, AEDesc *desiredTypes, AEDesc *dstList)
  937. {
  938.     OSErr            error        = noErr;
  939.     long            itemNum;
  940.     long            numItems;
  941.     DescType        keyword;
  942.     AEDesc        srcItem     = {typeNull, nil};
  943.     AEDesc        dstItem     = {typeNull, nil};
  944.         
  945.     error = AECountItems((AEDescList*)srcList, &numItems);
  946.     if (error != noErr)
  947.         goto CleanUp;
  948.         
  949.     for (itemNum = 1; itemNum <= numItems; itemNum++)
  950.     {
  951.        error = AEGetNthDesc(srcList, itemNum, typeWildCard, &keyword, &srcItem);
  952.         if (error != noErr)
  953.             goto CleanUp;
  954.         
  955.         if (TokenContainsTokenList(&srcItem) == false)
  956.         {
  957.             error = GetDataFromObject(&srcItem, desiredTypes, &dstItem);  // Get data from single item
  958.         }
  959.         else
  960.         {
  961.             error = AECreateList(NULL, 0L, false, &dstItem);
  962.             if (error == noErr)
  963.                 error = GetDataFromList(&srcItem, desiredTypes, &dstItem);
  964.         }
  965.         if (error != noErr)
  966.             goto CleanUp;
  967.  
  968.         error = AEPutDesc(dstList, itemNum, &dstItem);
  969.         if (error != noErr)
  970.             goto CleanUp;
  971.                 
  972.         AEDisposeDesc(&srcItem);
  973.         AEDisposeDesc(&dstItem);
  974.     }
  975.     
  976. CleanUp:
  977.  
  978.     AEDisposeDesc(&srcItem);
  979.     AEDisposeDesc(&dstItem);
  980.  
  981.     return error;
  982. }
  983.  
  984. //----------------------------------------------------------------------------------
  985. //    GetDataFromObject
  986. //
  987. // Extract the window reference from a token and then return the property the user requested
  988. //
  989. //----------------------------------------------------------------------------------
  990.  
  991. static OSErr 
  992. GetDataFromObject(AEDesc *token, AEDesc *desiredTypes, AEDesc *data)
  993. {
  994.     #pragma unused (desiredTypes)
  995.  
  996.     OSErr                    error                    = noErr;
  997.     Boolean                usePropertyCode    = false;    
  998.     WindowPtr            window;
  999.     WindowPtr          tempWindow;
  1000.     
  1001.     DescType                aType = cWindow;
  1002.     Rect                    aRect;
  1003.     
  1004.     Point                    aPoint;
  1005.     Boolean                aBoolean;
  1006.     long                    index;
  1007.     Str255                windowTitle;
  1008.     
  1009.     usePropertyCode = ExtractUsePropertyCodeFromToken(token);
  1010.     window          = ExtractWindowPtrFromToken(token);
  1011.  
  1012.     GetWTitle((WindowPtr)window, windowTitle);
  1013.  
  1014.     // compute this window's index from front
  1015.  
  1016.     tempWindow = GetFirstWindow();
  1017.     index          = 1L;
  1018.     
  1019.     while (tempWindow != nil && window != tempWindow)
  1020.     {
  1021.         index++;
  1022.         tempWindow = (WindowPtr)GetNextWindow(tempWindow);
  1023.     }
  1024.     
  1025.     if (usePropertyCode == false)
  1026.     {
  1027.         error = errAECantSupplyType;
  1028.     }
  1029.     else
  1030.     {
  1031.         DescType propertyCode = ExtractPropertyCodeFromToken(token);
  1032.         
  1033.         switch (propertyCode)
  1034.         {
  1035.             case pProperties:
  1036.                 error = AECreateList(NULL, 0L, true, data);
  1037.                 if (error != noErr)
  1038.                     goto CleanUp;
  1039.  
  1040.                 error = AEPutKeyPtr(data, pObjectType, typeType, &aType, sizeof(DescType));
  1041.  
  1042.                 error = AEPutKeyPtr(data, pTitle,  typeChar, &windowTitle[1], windowTitle[0]);
  1043.                 error = AEPutKeyPtr(data, pIndex, typeLongInteger, &index, sizeof(long));
  1044.  
  1045.                 GetWindowBounds(window, &aRect);
  1046.                 error = AEPutKeyPtr(data, pBounds, typeQDRectangle, &aRect, sizeof(Rect));
  1047.                 aPoint.h = aRect.left;
  1048.                 aPoint.v = aRect.top;
  1049.                 error = AEPutKeyPtr(data, pLocation, typeQDPoint, &aPoint, sizeof(Point));
  1050.                 
  1051.                 aBoolean = WindowHasCloseBox(window);
  1052.                 error = AEPutKeyPtr(data, pHasCloseBox, typeBoolean, &aBoolean, sizeof(Boolean));
  1053.  
  1054.                 aBoolean = (WindowHasCloseBox(window) || WindowHasZoomBox(window));
  1055.                 error = AEPutKeyPtr(data, pHasTitleBar, typeBoolean, &aBoolean, sizeof(Boolean));
  1056.  
  1057.                 aBoolean = WindowIsModal(window);
  1058.                 error = AEPutKeyPtr(data, pIsModal, typeBoolean, &aBoolean, sizeof(Boolean));
  1059.  
  1060.                 aBoolean = (WindowHasZoomBox(window) || WindowHasGrowIcon(window));
  1061.                 error = AEPutKeyPtr(data, pIsResizable, typeBoolean, &aBoolean, sizeof(Boolean));
  1062.  
  1063.                 aBoolean = WindowHasZoomBox(window);
  1064.                 error = AEPutKeyPtr(data, pIsZoomable, typeBoolean, &aBoolean, sizeof(Boolean));
  1065.  
  1066.                 aBoolean = WindowHasZoomBox(window);
  1067.                 error = AEPutKeyPtr(data, pIsZoomed, typeBoolean, &aBoolean, sizeof(Boolean));
  1068.                 
  1069.                 aBoolean = WindowIsModeless(window);
  1070.                 error = AEPutKeyPtr(data, pIsModeless, typeBoolean, &aBoolean, sizeof(Boolean));
  1071.                 
  1072.                 aBoolean = WindowIsMovableModal(window);
  1073.                 error = AEPutKeyPtr(data, pIsMovableModal, typeBoolean, &aBoolean, sizeof(Boolean));
  1074.                                                 
  1075.                 aBoolean = ((WindowPeek)window)->visible;
  1076.                 error = AEPutKeyPtr(data, pVisible, typeBoolean, &aBoolean, sizeof(Boolean));
  1077.                                                 
  1078.                 break;
  1079.                                 
  1080.             case pBestType:
  1081.             case pClass:
  1082.             case pDefaultType:
  1083.             case pObjectType:
  1084.                 error = AECreateDesc(typeType, &aType, sizeof(DescType), data);
  1085.                 break;
  1086.                 
  1087.             case pBounds:
  1088.                 GetWindowBounds(window, &aRect);
  1089.                 error = AECreateDesc(typeQDRectangle, &aRect, sizeof(Rect), data);
  1090.                 break;
  1091.                 
  1092.             case pLocation:
  1093.                 GetWindowBounds(window, &aRect);
  1094.                 aPoint.h = aRect.left;
  1095.                 aPoint.v = aRect.top;
  1096.                 error = AECreateDesc(typeQDPoint, &aPoint, sizeof(Point), data);
  1097.                 break;
  1098.                 
  1099.             case pIsModeless:
  1100.                 aBoolean = WindowIsModeless(window);
  1101.                 error = AECreateDesc(typeBoolean, &aBoolean, sizeof(Boolean), data);
  1102.                 break;
  1103.                 
  1104.             case pIsMovableModal:
  1105.                 aBoolean = WindowIsMovableModal(window);
  1106.                 error = AECreateDesc(typeBoolean, &aBoolean, sizeof(Boolean), data);
  1107.                 break;
  1108.                                                 
  1109.             case pHasCloseBox:
  1110.                 aBoolean = WindowHasCloseBox(window);
  1111.                 error = AECreateDesc(typeBoolean, &aBoolean, sizeof(Boolean), data);
  1112.                 break;
  1113.                 
  1114.             case pHasTitleBar:
  1115.                 aBoolean = (WindowHasCloseBox(window) || WindowHasZoomBox(window));
  1116.                 error = AECreateDesc(typeBoolean, &aBoolean, sizeof(Boolean), data);
  1117.                 break;
  1118.                 
  1119.             case pIndex:
  1120.                 error = AECreateDesc(typeLongInteger, &index, sizeof(long), data);
  1121.                 break;
  1122.                                 
  1123.             case pIsModal:
  1124.                 aBoolean = WindowIsModal(window);
  1125.                 error = AECreateDesc(typeBoolean, &aBoolean, sizeof(Boolean), data);
  1126.                 break;
  1127.                 
  1128.             case pIsResizable:
  1129.                 aBoolean = (WindowHasZoomBox(window) || WindowHasGrowIcon(window));
  1130.                 error = AECreateDesc(typeBoolean, &aBoolean, sizeof(Boolean), data);
  1131.                 break;
  1132.                 
  1133.             case pIsZoomable:
  1134.                 aBoolean = WindowHasZoomBox(window);
  1135.                 error = AECreateDesc(typeBoolean, &aBoolean, sizeof(Boolean), data);
  1136.                 break;
  1137.                 
  1138.             case pIsZoomed:
  1139.                 aBoolean = WindowHasZoomBox(window);
  1140.                 error = AECreateDesc(typeBoolean, &aBoolean, sizeof(Boolean), data);
  1141.                 break;
  1142.                 
  1143.             case pVisible:
  1144.                 aBoolean = WindowIsVisible(window);
  1145.                 error = AECreateDesc(typeBoolean, &aBoolean, sizeof(Boolean), data);
  1146.                 break;
  1147.                 
  1148.             case pName:        // Synonym for pTitle
  1149.             case pTitle:
  1150.                 error = AECreateDesc(typeChar, &windowTitle[1], windowTitle[0], data);
  1151.                 break;
  1152.                                 
  1153.             deafult:
  1154.                 error = errAECantSupplyType;
  1155.         }
  1156.     }
  1157.     
  1158. CleanUp:
  1159.     
  1160.     return error;
  1161. }
  1162.  
  1163. #pragma mark -
  1164. // -------------------------------------------------------------------------------------------
  1165. //
  1166. //   SetDataFromWindowTokenList
  1167. //
  1168. // Given a token that contains a list of cWindow tokens,
  1169. // walk the list recursively to set the data for each token in the list
  1170. //
  1171. // -------------------------------------------------------------------------------------------
  1172.  
  1173. static OSErr
  1174. SetDataForList(AEDesc *token, AEDesc *data)
  1175. {
  1176.     OSErr             error          = noErr;    
  1177.     AEDesc              tempToken      = {typeNull, nil};
  1178.     
  1179.     long                numItems;
  1180.     long                itemNum;
  1181.     AEKeyword        keyword;
  1182.         
  1183.     if (TokenContainsTokenList(token) == false)
  1184.     {
  1185.         error = SetDataForObject(token, data);
  1186.     }
  1187.     else
  1188.     {
  1189.         error = AECountItems((AEDescList*)token, &numItems);
  1190.         if (error != noErr)
  1191.             goto CleanUp;
  1192.         
  1193.         for (itemNum = 1; itemNum <= numItems; itemNum++)
  1194.         {
  1195.            error = AEGetNthDesc((AEDescList*)token, itemNum, typeWildCard, &keyword, &tempToken);
  1196.             if (error != noErr)
  1197.                 goto CleanUp;
  1198.             
  1199.             if (TokenContainsTokenList(&tempToken) == false)
  1200.             {
  1201.                 error = SetDataForObject(&tempToken, data);          // Set data from single item
  1202.             }
  1203.             else
  1204.             {
  1205.                 error = SetDataForList(&tempToken, data);     // Recurse sublist
  1206.             }
  1207.             if (error != noErr)
  1208.                 goto CleanUp;
  1209.                     
  1210.             AEDisposeDesc(&tempToken);
  1211.         }
  1212.     }
  1213.  
  1214. CleanUp:
  1215.     
  1216.     AEDisposeDesc(&tempToken);
  1217.     
  1218.     return error;
  1219. }
  1220.  
  1221. //----------------------------------------------------------------------------------
  1222. //
  1223. //    SetDataForToken()
  1224. //
  1225. //----------------------------------------------------------------------------------
  1226. // Assumption: HandleSetData() has already filtered out all attempts
  1227. // to write to a read-only property.
  1228.  
  1229. // Extract the document reference from a token, get its ad reference,
  1230. // and then store the data we received into the requested property
  1231.  
  1232. static OSErr 
  1233. SetDataForObject(AEDesc *token, AEDesc *data)
  1234. {
  1235.  
  1236.     OSErr                    error            = noErr;
  1237.         
  1238.     Boolean                usePropertyCode;
  1239.     DescType                propertyCode;
  1240.     WindowPtr      window         = nil;
  1241.     
  1242.     AEDesc propertyRecord             = {typeNull, nil};
  1243.  
  1244.     usePropertyCode = ExtractUsePropertyCodeFromToken(token);
  1245.     
  1246.     window = ExtractWindowPtrFromToken(token);
  1247.         
  1248.     if (usePropertyCode == false)
  1249.     {
  1250.         error = errAEWriteDenied;
  1251.     }
  1252.     else
  1253.     {
  1254.         propertyCode = ExtractPropertyCodeFromToken(token);
  1255.         
  1256.         // Convert the single property to a record containing one property
  1257.  
  1258.         if (data->descriptorType == typeAERecord)
  1259.         {        
  1260.             error = SetProperties(window, data);
  1261.         }
  1262.         else    // Build a record with one property
  1263.         {
  1264.             error = AECreateList(NULL, 0L, true, &propertyRecord);
  1265.             if (error != noErr)
  1266.                 goto CleanUp;
  1267.             
  1268.             error = AEPutKeyDesc(&propertyRecord, propertyCode, data);
  1269.             if (error != noErr)
  1270.                 goto CleanUp;
  1271.         
  1272.             error = SetProperties(window, &propertyRecord);
  1273.         }
  1274.     }
  1275.  
  1276. CleanUp:
  1277.  
  1278.     AEDisposeDesc(&propertyRecord);
  1279.  
  1280.     return error;
  1281. }
  1282.  
  1283.  
  1284. //----------------------------------------------------------------------------------
  1285. //                                           SetProperties
  1286. //----------------------------------------------------------------------------------
  1287. // Set an object's properties from the record we receive
  1288.  
  1289. static OSErr 
  1290. SetProperties(WindowPtr window, AEDesc *propertyRecord)
  1291. {
  1292.     #pragma unused (window)
  1293.  
  1294.     OSErr                 error             = noErr;
  1295.     OSErr                 ignoreError     = noErr;
  1296.         
  1297.     long                     numProperties     = 0L;
  1298.         
  1299.     AEDesc                 data                 = {typeNull, nil};
  1300.     
  1301.     GrafPtr                curPort;
  1302.     
  1303.     GetPort(&curPort);
  1304.     SetPort(window);
  1305.     
  1306.     if (propertyRecord == NULL || propertyRecord->descriptorType != typeAERecord)
  1307.     {
  1308.         error = errAEWrongDataType;
  1309.         goto CleanUp;
  1310.     }
  1311.                 
  1312.     error = AECountItems(propertyRecord, &numProperties);
  1313.         
  1314.     if (error != noErr || numProperties <= 0)
  1315.         goto CleanUp;
  1316.         
  1317.     // pBounds
  1318.     
  1319.     ignoreError = AEGetKeyDesc(propertyRecord, pBounds, typeQDRectangle, &data);
  1320.     if (ignoreError != errAEDescNotFound)
  1321.     {
  1322.         Rect r;
  1323.         error = DescToRect(&data, &r);
  1324.  
  1325.         if (error == noErr)
  1326.         {        
  1327.             short windowWidth =  r.right - r.left;
  1328.             short windowDepth =  r.bottom - r.top;
  1329.                 
  1330.             InvalRect(&window->portRect);                
  1331.              MoveWindow(window, r.left, r.top, false);
  1332.              SizeWindow(window, windowWidth, windowDepth, true);
  1333.              InvalRect(&window->portRect);
  1334.         }                    
  1335.         AEDisposeDesc(&data);
  1336.     }
  1337.  
  1338.     // pLocation
  1339.     
  1340.     ignoreError = AEGetKeyDesc(propertyRecord, pLocation, typeQDPoint, &data);
  1341.     if (ignoreError != errAEDescNotFound)
  1342.     {
  1343.         Point p;
  1344.         error = DescToPoint(&data, &p);
  1345.  
  1346.         if (error == noErr)
  1347.             MoveWindow(window, p.h, p.v, false);  // don't let Window Manager bring it to front!
  1348.  
  1349.         AEDisposeDesc(&data);
  1350.     }
  1351.  
  1352.     // pIndex
  1353.     
  1354.     ignoreError = AEGetKeyDesc(propertyRecord, pIndex, typeLongInteger, &data);
  1355.     if (ignoreError != errAEDescNotFound)
  1356.     {
  1357.         long             index;
  1358.         long             numWindows;
  1359.         WindowPtr     behindWindow;
  1360.         
  1361.         error = DescToLong(&data, &index);
  1362.  
  1363.         if (error == noErr)
  1364.         {    
  1365.             numWindows = CountWindows();
  1366.             if (index < 0)
  1367.                 index = numWindows + index + 1;
  1368.             
  1369.             if (index == 1)
  1370.             {
  1371.                 SelectWindow(window);
  1372.             }
  1373.             else
  1374.             {
  1375.                 behindWindow = GetWindowByIndex(index);
  1376.                 if (behindWindow != NULL)
  1377.                 {
  1378.                     SendBehind(window, behindWindow);
  1379.                 }
  1380.                 else
  1381.                 {
  1382.                     error = errAEEventNotHandled;
  1383.                 }
  1384.             }
  1385.         }                    
  1386.  
  1387.         AEDisposeDesc(&data);
  1388.     }
  1389.  
  1390.  
  1391.     // pIsZoomed
  1392.     
  1393.     ignoreError = AEGetKeyDesc(propertyRecord, pIsZoomed, typeBoolean, &data);
  1394.     if (ignoreError != errAEDescNotFound)
  1395.     {
  1396.         Boolean     zoomIt;
  1397.         
  1398.         error = DescToBoolean(&data, &zoomIt);
  1399.         
  1400.         if (error == noErr)
  1401.         {
  1402.             EraseRect(&window->portRect);
  1403.             
  1404.             if (zoomIt)
  1405.                 ZoomWindow(window, inZoomOut, false);
  1406.             else
  1407.                 ZoomWindow(window, inZoomIn, false);
  1408.                 
  1409.             InvalRect(&window->portRect);
  1410.         }                    
  1411.  
  1412.         AEDisposeDesc(&data);
  1413.     }
  1414.  
  1415.     // pVisible
  1416.     
  1417.     ignoreError = AEGetKeyDesc(propertyRecord, pVisible, typeBoolean, &data);
  1418.     if (ignoreError != errAEDescNotFound)
  1419.     {
  1420.         Boolean showIt;
  1421.         error = DescToBoolean(&data, &showIt);
  1422.         
  1423.         if (error == noErr)
  1424.         {
  1425.             if (showIt)
  1426.                 ShowWindow(window);
  1427.             else
  1428.                 HideWindow(window);
  1429.         }                    
  1430.  
  1431.         AEDisposeDesc(&data);
  1432.     }
  1433.  
  1434. CleanUp:
  1435.  
  1436.     SetPort(curPort);
  1437.     AEDisposeDesc(&data);
  1438.  
  1439.     return error;
  1440. }
  1441.  
  1442. #pragma mark -
  1443. //----------------------------------------------------------------------------------
  1444.  
  1445. static Boolean
  1446. CanGetProperty(DescType property)
  1447. {
  1448.     Boolean    result = false;
  1449.     
  1450.     switch (property)
  1451.     {
  1452.         // Properties we can get:
  1453.         
  1454.         case pBestType:
  1455.         case pClass:
  1456.         case pDefaultType:
  1457.         case pObjectType:
  1458.                 
  1459.         case pProperties:
  1460.         
  1461.         case pTitle:
  1462.         case pName:    // Synonym for pTitle
  1463.         
  1464.         case pIsModeless:
  1465.         case pIsMovableModal:
  1466.         case pIsSuspended:
  1467.         case pIsPalette:
  1468.         case pIsDialog:
  1469.         
  1470.         case pBounds:
  1471.         case pLocation:
  1472.  
  1473.         case pHasCloseBox:
  1474.         case pHasTitleBar:
  1475.         case pIndex:
  1476.  
  1477.         case pIsFloating:
  1478.         case pIsModal:
  1479.         case pIsResizable:
  1480.         case pIsZoomable:
  1481.  
  1482.         case pIsZoomed:
  1483.         case pVisible:
  1484.             result = true;
  1485.             break;
  1486.             
  1487.         // Properties we can't get:
  1488.         default:
  1489.             result = false;
  1490.             break;
  1491.     }
  1492.  
  1493.     return result;
  1494. }
  1495.  
  1496. //----------------------------------------------------------------------------------
  1497.  
  1498. static Boolean
  1499. CanSetProperty(DescType property)
  1500. {
  1501.     Boolean    result = false;
  1502.         
  1503.     switch (property)
  1504.     {
  1505.         // Properties we can set:
  1506.                         
  1507.         case pProperties:
  1508.             result = true;
  1509.             break;
  1510.             
  1511.         // Properties that can be set only for certain types of windows:
  1512.         
  1513.         case pTitle:
  1514.         case pName:    // Synonym for pTitle
  1515.  
  1516.         case pBounds:
  1517.         case pLocation:
  1518.         case pIndex:
  1519.         case pVisible:
  1520.         case pIsZoomed:
  1521.             result = true;
  1522.             break;
  1523.         
  1524.         // Properties we should be able to set, but not implemented yet:
  1525.  
  1526.  
  1527.         // Properties we can't set:
  1528.  
  1529.         default:
  1530.         case pBestType:
  1531.         case pClass:
  1532.         case pDefaultType:
  1533.         case pObjectType:
  1534.                 
  1535.         case pIsModeless:
  1536.         case pIsMovableModal:
  1537.         case pIsSuspended:
  1538.         case pIsPalette:
  1539.         case pIsDialog:
  1540.  
  1541.         case pHasCloseBox:
  1542.         case pHasTitleBar:
  1543.  
  1544.         case pIsFloating:
  1545.         case pIsModal:
  1546.         case pIsResizable:
  1547.         case pIsZoomable:
  1548.             result = false;
  1549.             break;
  1550.     }
  1551.  
  1552.     return result;
  1553. }
  1554.  
  1555. #pragma mark -
  1556. //----------------------------------------------------------------------------------
  1557. //            Application-Specific code triggered by a similarly-named HandleXXX()
  1558. //----------------------------------------------------------------------------------
  1559.  
  1560. static OSErr 
  1561. DoClose(AEDesc *token, const AEDesc *saving, AEDesc *savingIn)
  1562. {
  1563.     #pragma unused (token, saving, savingIn)
  1564.  
  1565.     OSErr                    error            = noErr;
  1566.     DocumentReference document;
  1567.  
  1568.     error = GetDocumentReferenceFromToken(token, &document);
  1569.     
  1570.     if (error == noErr && document != nil)
  1571.         DestroyDocument(document);
  1572.     else
  1573.         error = errAEEventNotHandled;
  1574.     
  1575.     return error;
  1576. }
  1577.  
  1578. //----------------------------------------------------------------------------------
  1579. // Open a window object
  1580. //----------------------------------------------------------------------------------
  1581.  
  1582. static OSErr 
  1583. DoOpen(AEDesc *token)
  1584. {
  1585.     #pragma unused (token)
  1586.  
  1587.     OSErr error = errAEEventNotHandled;
  1588.  
  1589.     return error;
  1590. }
  1591.  
  1592. #pragma mark -
  1593. // -------------------------------------------------------------------------------------------
  1594.  
  1595. static OSErr 
  1596. ProcessFormRelativePostition(const AEDesc* anchorToken, const AEDesc *keyData, WindowPtr *window)
  1597. {
  1598.     OSErr        error = noErr;
  1599.     
  1600.     DescType positionEnum;    
  1601.     WindowPtr anchorWindow;
  1602.     WindowPtr relativeWindow = nil;
  1603.     
  1604.     *window = NULL;
  1605.     
  1606.     anchorWindow = ExtractWindowPtrFromToken(anchorToken);
  1607.  
  1608.     if (anchorWindow != NULL)
  1609.     {
  1610.     
  1611.         switch (keyData->descriptorType)
  1612.         {
  1613.            case typeEnumerated:
  1614.                 if (DescToDescType((AEDesc*)keyData, &positionEnum) != noErr)
  1615.                 {
  1616.                     error = errAECoercionFail;
  1617.                 }
  1618.                 else
  1619.                 {
  1620.                     switch (positionEnum)
  1621.                     {
  1622.                         case kAENext:                        // get the window behind the anchor
  1623.                             *window = GetNextWindow(anchorWindow);
  1624.                             if (*window == NULL)
  1625.                                 error = errAENoSuchObject;
  1626.                             break;
  1627.                             
  1628.                         case kAEPrevious:                    // get the document in front of the anchor
  1629.                             *window = GetPreviousWindow(anchorWindow);
  1630.                             if (*window == NULL)
  1631.                                 error = errAENoSuchObject;
  1632.                             break;
  1633.                             
  1634.                         default:
  1635.                             error = errAEEventNotHandled;
  1636.                             break;
  1637.                     }
  1638.                 }
  1639.                 break;
  1640.                 
  1641.             default:
  1642.                 error = errAECoercionFail;
  1643.                 break;
  1644.         }
  1645.     }
  1646.     
  1647.     return error;
  1648. }
  1649.  
  1650. // -------------------------------------------------------------------------------------------
  1651.